import Data from "../object/Data"
import ObservableMap from "../observer/observable.map"
import ObservableValue from "../observer/observable.value"
import ExtObj from "./ExtObj"
import ExtObjData from "./ExtObjData"
import ExtObjState from "./ExtObjState"
interface derivedItem {
  id: string
  position: THREE.Vector3
  enable: boolean
  name: string
}
export default class ExtObjViewData extends Data {
  data: ExtObjData
  states: ObservableMap<ExtObjState>
  derivedData: Record<string, derivedItem>
  selectedExtObjObservable: ObservableValue<string>
  constructor(data: ExtObjData) {
    super()
    this.name = "extobj-view"
    this.data = data
    this.states = new ObservableMap()
    this.derivedData = {}
    this.selectedExtObjObservable = new ObservableValue(null)
    data.makeExtObjChangeSubscription(() => {
      this.selectCurrentExtObj()
    })
  }

  get selectedExtObj() {
    return this.selectedExtObjObservable.value
  }
  selectCurrentExtObj() {
    this.setSelectedExtObj(this.data.currentExtObj || null)
  }
  setSelectedExtObj(e: string) {
    if (e === this.selectedExtObj) return
    const t = this.selectedExtObj
    this.selectedExtObjObservable.value = e
    if (null !== e) {
      const t = this.getState(e)
      t.selected = !0
      t.commit()
    }
    if (null !== t) {
      const e = this.getState(t)
      e.selected = !1
      e.commit()
    }
  }
  getState(e: string) {
    return this.states.get(e)
  }
  isVisible(e: string) {
    return this.states.get(e).visible
  }
  setVisible(e: string, visible) {
    const i = this.getState(e)
    i.visible !== visible && ((i.visible = visible), i.commit())
  }
  iterate(e: (v: ExtObj, i?: number) => void) {
    this.data.iterate(e)
  }
  getViewData(e: string) {
    const t = this.data.getExtObj(e)
    const i = this.derivedData[e]
    t && !i && (this.derivedData[e] = this.makeViewDataForExtObj(t))
    return this.derivedData[e]
  }
  makeViewDataForExtObj(e: ExtObj) {
    const i: derivedItem = this.derivedData[e.id] || {
      id: e.id,
      position: e.position,
      enable: e.enable,
      name: e.name
    }
    return i
  }
}
